/*
 * jxDao Project (2014)
 * 
 * by Denilson Edinaldo Pinto
 * 
 * LGPL
 * Copyright (C) 2014
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
package org.jxDao.dao.filter;

import java.io.Serializable;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Date;

/**
 * @author Denilson Edinaldo Pinto
 * @porject jxDao
 * @package org.jxDao.dao.filter
 * @date 14/04/2014 - 11:04:05
 */
public interface Filterable extends Serializable, Cloneable {
	
	/**
	 * @return the columnName
	 */
	String getColumnName();
	
	/**
	 * @return the operator
	 */
	FilterOperator getOperator();
	
	/**
	 * @return the value
	 */
	Object getValue();
	
	/**
	 * @return the groupBy
	 */
	GroupBy getGroupBy();
	
	/**
	 * @return the orderBy
	 */
	OrderBy getOrderBy();
	
	/**
	 * @return clone this Filter
	 */
	Filterable clone();
	
	/**
	 * @param filters
	 * @return this {@link Filterable}
	 */
	Filterable and(Filterable... filters);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andBetween(String columnName, Date start, Date end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andBetween(String columnName, Number start, Number end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andBetween(String columnName, Object start, Object end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andBetween(String columnName, Time start, Time end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andBetween(String columnName, Timestamp start, Timestamp end);
	
	/**
	 * @param sql
	 * @return {@link Filterable}
	 */
	Filterable andCustom(String sql);
	
	/**
	 * @param sql
	 * @param groupBy
	 * @return {@link Filterable}
	 */
	Filterable andCustom(String sql, GroupBy groupBy);
	
	/**
	 * @param sql
	 * @param groupBy
	 * @param orderBy
	 * @return {@link Filterable}
	 */
	Filterable andCustom(String sql, GroupBy groupBy, OrderBy orderBy);
	
	/**
	 * @param sql
	 * @param orderBy
	 * @return {@link Filterable}
	 */
	Filterable andCustom(String sql, OrderBy orderBy);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @param isMD5Value
	 * @return this {@link Filterable}
	 */
	Filterable andEqual(String columnName, Object value, boolean isMD5Value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterOrEqual(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterOrEqual(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterOrEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterOrEqual(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterOrEqual(String columnName, Timestamp value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterThan(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterThan(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterThan(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterThan(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andGreaterThan(String columnName, Timestamp value);
	
	/**
	 * columnName LIKE UPPER('%value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andILikeBetween(String columnName, String value);
	
	/**
	 * columnName LIKE UPPER('%value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andILikeEnd(String columnName, String value);
	
	/**
	 * columnName LIKE UPPER('value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andILikeEqual(String columnName, String value);
	
	/**
	 * columnName LIKE UPPER('value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andILikeStart(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable andIn(String columnName, Collection<?> values);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable andIn(String columnName, Object[] values);
	
	/**
	 * @param columnName
	 * @return this {@link Filterable}
	 */
	Filterable andIsNotNull(String columnName);
	
	/**
	 * @param columnName
	 * @return this {@link Filterable}
	 */
	Filterable andIsNull(String columnName);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessOrEqual(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessOrEqual(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessOrEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessOrEqual(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessOrEqual(String columnName, Timestamp value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessThan(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessThan(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessThan(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessThan(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLessThan(String columnName, Timestamp value);
	
	/**
	 * columnName LIKE '%value%'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLikeBetween(String columnName, String value);
	
	/**
	 * columnName LIKE '%value'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLikeEnd(String columnName, String value);
	
	/**
	 * columnName LIKE 'value'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLikeEqual(String columnName, String value);
	
	/**
	 * columnName LIKE 'value%'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andLikeStart(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andNotBetween(String columnName, Date start, Date end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andNotBetween(String columnName, Number start, Number end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andNotBetween(String columnName, Object start, Object end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andNotBetween(String columnName, Time start, Time end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable andNotBetween(String columnName, Timestamp start, Timestamp end);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @param isMD5Value
	 * @return this {@link Filterable}
	 */
	Filterable andNotEqual(String columnName, Object value, boolean isMD5Value);
	
	/**
	 * columnName NOT LIKE UPPER('%value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotILikeBetween(String columnName, String value);
	
	/**
	 * columnName NOT LIKE UPPER('%value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotILikeEnd(String columnName, String value);
	
	/**
	 * columnName NOT LIKE UPPER('value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotILikeEqual(String columnName, String value);
	
	/**
	 * columnName NOT LIKE UPPER('value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotILikeStart(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable andNotIn(String columnName, Collection<?> values);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable andNotIn(String columnName, Object[] values);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotLikeBetween(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotLikeEnd(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotLikeEqual(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable andNotLikeStart(String columnName, String value);
	
	/**
	 * @param filters
	 * @return this {@link Filterable}
	 */
	Filterable or(Filterable... filters);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orBetween(String columnName, Date start, Date end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orBetween(String columnName, Number start, Number end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orBetween(String columnName, Object start, Object end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orBetween(String columnName, Time start, Time end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orBetween(String columnName, Timestamp start, Timestamp end);
	
	/**
	 * @param sql
	 * @return {@link Filterable}
	 */
	Filterable orCustom(String sql);
	
	/**
	 * @param sql
	 * @param groupBy
	 * @return {@link Filterable}
	 */
	Filterable orCustom(String sql, GroupBy groupBy);
	
	/**
	 * @param sql
	 * @param groupBy
	 * @param orderBy
	 * @return {@link Filterable}
	 */
	Filterable orCustom(String sql, GroupBy groupBy, OrderBy orderBy);
	
	/**
	 * @param sql
	 * @param orderBy
	 * @return {@link Filterable}
	 */
	Filterable orCustom(String sql, OrderBy orderBy);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @param isMD5Value
	 * @return this {@link Filterable}
	 */
	Filterable orEqual(String columnName, Object value, boolean isMD5Value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterOrEqual(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterOrEqual(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterOrEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterOrEqual(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterOrEqual(String columnName, Timestamp value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterThan(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterThan(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterThan(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterThan(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orGreaterThan(String columnName, Timestamp value);
	
	/**
	 * columnName LIKE UPPER('%value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orILikeBetween(String columnName, String value);
	
	/**
	 * columnName LIKE UPPER('%value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orILikeEnd(String columnName, String value);
	
	/**
	 * columnName LIKE UPPER('value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orILikeEqual(String columnName, String value);
	
	/**
	 * columnName LIKE UPPER('value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orILikeStart(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable orIn(String columnName, Collection<?> values);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable orIn(String columnName, Object[] values);
	
	/**
	 * @param columnName
	 * @return this {@link Filterable}
	 */
	Filterable orIsNotNull(String columnName);
	
	/**
	 * @param columnName
	 * @return this {@link Filterable}
	 */
	Filterable orIsNull(String columnName);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessOrEqual(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessOrEqual(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessOrEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessOrEqual(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessOrEqual(String columnName, Timestamp value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessThan(String columnName, Date value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessThan(String columnName, Number value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessThan(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessThan(String columnName, Time value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLessThan(String columnName, Timestamp value);
	
	/**
	 * columnName LIKE '%value%'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLikeBetween(String columnName, String value);
	
	/**
	 * columnName LIKE '%value'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLikeEnd(String columnName, String value);
	
	/**
	 * columnName LIKE 'value'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLikeEqual(String columnName, String value);
	
	/**
	 * columnName LIKE 'value%'
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orLikeStart(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orNotBetween(String columnName, Date start, Date end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orNotBetween(String columnName, Number start, Number end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orNotBetween(String columnName, Object start, Object end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orNotBetween(String columnName, Time start, Time end);
	
	/**
	 * @param columnName
	 * @param start
	 * @param end
	 * @return this {@link Filterable}
	 */
	Filterable orNotBetween(String columnName, Timestamp start, Timestamp end);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotEqual(String columnName, Object value);
	
	/**
	 * @param columnName
	 * @param value
	 * @param isMD5Value
	 * @return this {@link Filterable}
	 */
	Filterable orNotEqual(String columnName, Object value, boolean isMD5Value);
	
	/**
	 * columnName NOT LIKE UPPER('%value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotILikeBetween(String columnName, String value);
	
	/**
	 * columnName NOT LIKE UPPER('%value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotILikeEnd(String columnName, String value);
	
	/**
	 * columnName NOT LIKE UPPER('value')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotILikeEqual(String columnName, String value);
	
	/**
	 * columnName NOT LIKE UPPER('value%')
	 * 
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotILikeStart(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable orNotIn(String columnName, Collection<?> values);
	
	/**
	 * @param columnName
	 * @param values
	 * @return this {@link Filterable}
	 */
	Filterable orNotIn(String columnName, Object[] values);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotLikeBetween(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotLikeEnd(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotLikeEqual(String columnName, String value);
	
	/**
	 * @param columnName
	 * @param value
	 * @return this {@link Filterable}
	 */
	Filterable orNotLikeStart(String columnName, String value);
	
	/**
	 * @param groupBy
	 * @return this {@link Filterable}
	 */
	Filterable groupBy(final GroupBy groupBy);
	
	/**
	 * @param orderBy
	 * @return this {@link Filterable}
	 */
	Filterable orderBy(OrderBy orderBy);
}
